# -*- encoding: utf-8 -*-
"""
File Name: sync_zabbix_snmp_device_monitor
Description:
Author : 'lirui'
date: 2/6/2024
Contact: marjey_lee@163.com
Change Activity:
2/6/2024:
"""
from modules.blk.cmdb.cmdb_service import CMDBService
import ll
from projects.generation.create_zabbix_device_snmp_monitor.utils.container_client_mapping import get_zabbix_clients_mapping


class SyncZabbixSnmpDeviceMonitor:
    def __init__(self):
        self.zabbix_login_info = self._load_zabbix_server_login_info()
        self.network_device_asset_info = self._load_all_network_device_asset_info()  # cmdb
        self.snmp_info = self.load_all_snmp_info()  # cmdb

    @staticmethod
    def _load_zabbix_server_login_info():
        """

        Returns:

        """
        data = CMDBService().select('zabbix_docker_info')
        data = data['data']['info']
        ll.log(f'Load data from CMDB, total size is {len(data)}')
        return data

    def __call__(self):
        ll.log(f'Start to create zabbix snmp monitoring items.')
        self._check_cmdb_data()
        self._sync_data()

    def _check_cmdb_data(self):
        """
        check cmdb data
        Returns:

        """
        for device_ip in self.network_device_asset_info:
            if device_ip not in self.snmp_info:
                ll.get_logger().warning(f'{device_ip} info not record in zabbix snmp table.')
        for device_ip in self.snmp_info:
            if device_ip not in self.network_device_asset_info:
                ll.get_logger().warning(f'{device_ip} info not record in network device table.')

    def _sync_data(self):
        """

        Returns:

        """
        for ip, data in self.snmp_info.items():
            if data['is_use'] == '否':
                ll.get_logger().notice(f'skip {ip} for monitoring.')
                continue
            if ip not in self.network_device_asset_info:
                ll.get_logger().warning(f'{ip} info not record in network device table.')
                continue
            asset_info = self.network_device_asset_info[ip]
            equipment_name = asset_info['equipment_name']
            zabbix_server_id = data['zabbix_server_id']
            snmp_community = data['snmp_community']
            self._handle_host(equipment_name, ip, zabbix_server_id, snmp_community)

    @staticmethod
    def _handle_host(equipment_name, ip, zabbix_server_id, snmp_community):
        """
        Args:
            equipment_name:
            ip:
            zabbix_server_id:
            snmp_community:
        Returns:
        """
        host_name = f'{equipment_name}_{ip}'.split()
        ll.get_logger().info(f'Start to handle {ip}')
        container_manager = get_zabbix_clients_mapping(ip, zabbix_server_id)
        host_id = container_manager.get_host_id(host_name)
        if host_id is not None:
            ll.get_logger().info(f'{ip} already exist in zabbix server.')
            return
        client = container_manager.get_client()
        t = client.get_template('group', 'get_groups')
        t['params']['filter']['name'] = 'Discovered hosts'
        group_id = client.fetch(t)[0]['groupid']
        t = client.get_template('template', 'get')
        t['params']['filter']['name'] = 'Network Generic Device by SNMP'
        template_id = client.fetch(t)[0]['templateid']
        t = client.get_template('host', 'create_snmp')
        t['params']['groups'][0]['groupid'] = group_id
        t['params']['host'] = ip
        t['params']['interfaces'][0]['ip'] = ip
        t['params']['interfaces'][0]['details']['community'] = snmp_community
        t['params']['templates'][0]['templateid'] = template_id
        client.insert(t)

    @staticmethod
    def _load_all_network_device_asset_info():
        """
        load all cmdb info.
        Returns:

        """
        ll.get_logger().info('Start to load all network device asset info from cmdb.')
        data = CMDBService().select('network_device_asset')
        assert data['data']['count'] > 0
        ll.get_logger().info(f"Load {data['data']['count']} network device asset info.")
        data = data['data']['info']
        mapping = {}
        for item in data:
            ip = item['bk_inst_name']
            mapping[ip] = item
        return mapping

    @staticmethod
    def load_all_snmp_info():
        """

        Returns:

        """
        ll.get_logger().info('Start to load all snmp info from cmdb.')
        data = CMDBService().select('zabbix_network_device')
        ll.get_logger().info(f"Load {data['data']['count']} snmp info.")
        assert data['data']['count'] > 0
        data = data['data']['info']
        mapping = {}
        for item in data:
            ip = item['bk_inst_name']
            mapping[ip] = item
        return mapping
